%::PROVIDES=(
	name	=> ["STOP_NBD","START_NBD","REFRESH_NBD"],
	desc	=> ["Stop DRBD resources","Start DRBD resources","Restart DRBD resources"],
	type	=> "request",
	code	=> \&::do_handle_stopnbd
);

sub ::do_handle_stopnbd {
my $args=shift;
my ($app,$vg,$lv,$h,$r,$cmd,$cmd2,$cmd3);
my $cmdname=$args->{"_CMDNAME"};
my ($nbdserver_lock,$nbdserver_lockr,$nbdclient_lock,$nbdclient_lockr);
my ($instance);

	if(!exists($args->{APP})) {
		logwarn("$cmdname request missing APP argument");
		return "MISSING_ARG";
	}
	if(exists($args->{VG})) {
		$vg=$args->{VG};
	}
	if(exists($args->{LV})) {
		$lv=$args->{LV};
	}
	if(exists($args->{INSTANCECOUNT})) {
		$instance=$args->{INSTANCECOUNT};
	} else {
		$instance=0;
	}

	$h=hostname;
	$app=$args->{APP};
	if(!exists($appmap->{$app})) {
		logwarn("Specified application is not registered");
		return "NOT_REGISTERED";
	}

	#################################################################
	# We now need to work out whether the application is running	#
	# on this node, and if so stop the client, otherwise attempt	#
	# to stop the server.						#
	#################################################################
	
	$app=$args->{APP};
	if(defined($vg) && defined($lv)) {
		$cmd2="--vg $vg --lv $lv";
	} else {
		$cmd2="";
	}

	if($cmdname eq "STOP_NBD") {
		if($appmap->{$app}->{NODE} eq $h) {
			if(!$ARG_nolocking && defined($cllockd_client)) {
				logmsg("Attempt to get lock for NBD_CLIENT");
				($nbdclient_lock,$nbdclient_lockr)=$cllockd_client->acquire(
					PID	=> $$, 
					CPROC	=> "$_PRG-$app",
					HOLD	=> 30,
					MAXWAIT	=> 32,
					INTERVAL=> 2,
					LOCK	=> "NBD_CLIENT");
				if(!$nbdclient_lock) {
					logwarn("Unable to acquire lock: $nbdclient_lockr");
				}
			}
			$cmd="/opt/linuxha14/bin/utils/drbd_tool --application $app $cmd2 --action=down --verbose --logcmd";
			if(!$ARG_nolocking && defined($cllockd_client)) {
				logmsg("Attempt to release lock for NBD_CLIENT");
				($nbdclient_lock,$nbdclient_lockr)=$cllockd_client->release(
					PID	=> $$, 
					CPROC	=> "$_PRG-$app",
					LOCK	=> "NBD_CLIENT");
				if(!$nbdclient_lock) {
					logwarn("Unable to release lock: $nbdserver_lockr");
				}
			}
		} else {
			if(!$ARG_nolocking && defined($cllockd_client)) {
				logmsg("Attempt to get lock for NBD_SERVER");
				($nbdserver_lock,$nbdserver_lockr)=$cllockd_client->acquire(
					PID	=> $$, 
					CPROC	=> "$_PRG-$app",
					HOLD	=> 30,
					MAXWAIT	=> 32,
					INTERVAL=> 2,
					LOCK	=> "NBD_SERVER");
				if(!$nbdserver_lock) {
					logwarn("Unable to acquire lock: $nbdserver_lockr");
				}
			}
			$cmd="/opt/linuxha14/bin/utils/drbd_tool --application $app $cmd2 --action=down --verbose --logcmd";
			if(!$ARG_nolocking && defined($cllockd_client)) {
				logmsg("Attempt to release lock for NBD_SERVER");
				($nbdserver_lock,$nbdserver_lockr)=$cllockd_client->release(
					PID	=> $$, 
					CPROC	=> "$_PRG-$app",
					LOCK	=> "NBD_CLIENT");
				if(!$nbdserver_lock) {
					logwarn("Unable to release lock: $nbdserver_lockr");
				}
			}
		}
	}

	if($cmdname eq "START_NBD") {
		if($appmap->{$app}->{NODE} eq $h) {
			if(!$ARG_nolocking && defined($cllockd_client)) {
				logmsg("Attempt to get lock for NBD_CLIENT");
				($nbdclient_lock,$nbdclient_lockr)=$cllockd_client->acquire(
					PID	=> $$, 
					CPROC	=> "$_PRG-$app",
					HOLD	=> 30,
					MAXWAIT	=> 32,
					INTERVAL=> 2,
					LOCK	=> "NBD_CLIENT");
				if(!$nbdclient_lock) {
					logwarn("Unable to acquire lock: $nbdclient_lockr");
				}
			}
			$cmd3="/opt/linuxha14/bin/utils/drbd_tool --application $app $cmd2 --action=start --verbose --logcmd";
			$cmd="/opt/linuxha14/bin/utils/drbd_tool --application $app $cmd2 --action=reconnect --verbose --logcmd";
			if(exists($args->{RENEWONSTANDALONE}) &&
				lc($args->{RENEWONSTANDALONE}) eq "yes") {
				$cmd.=" --renew_on_standalone";
			}
			if(!$ARG_nolocking && defined($cllockd_client)) {
				logmsg("Attempt to release lock for NBD_CLIENT");
				($nbdclient_lock,$nbdclient_lockr)=$cllockd_client->release(
					PID	=> $$, 
					CPROC	=> "$_PRG-$app",
					LOCK	=> "NBD_CLIENT");
				if(!$nbdclient_lock) {
					logwarn("Unable to release lock: $nbdserver_lockr");
				}
			}
		} else {
			if(!$ARG_nolocking && defined($cllockd_client)) {
				logmsg("Attempt to get lock for NBD_SERVER");
				($nbdserver_lock,$nbdserver_lockr)=$cllockd_client->acquire(
					PID	=> $$, 
					CPROC	=> "$_PRG-$app",
					HOLD	=> 30,
					MAXWAIT	=> 32,
					INTERVAL=> 2,
					LOCK	=> "NBD_SERVER");
				if(!$nbdserver_lock) {
					logwarn("Unable to acquire lock: $nbdserver_lockr");
				}
			}
			$cmd="/opt/linuxha14/bin/utils/drbd_tool --application $app $cmd2 --action=start --noprimary --verbose --logcmd";
			#################################################
			# We discard our data if we've not been able to	#
			# use it due to drbd 8.2.x split-brain.		#
			#################################################
			if($instance>=3) {
				$cmd="/opt/linuxha14/bin/utils/drbd_tool --application $app $cmd2 --action=start --discard_my_data --verbose --logcmd";
				$cmd3="/opt/linuxha14/bin/utils/drbd_tool --application $app $cmd2 --action=reconnect --discard_my_data --verbose --logcmd";
			} else {
				$cmd3=undef;
			}
			if(!$ARG_nolocking && defined($cllockd_client)) {
				logmsg("Attempt to release lock for NBD_SERVER");
				($nbdserver_lock,$nbdserver_lockr)=$cllockd_client->release(
					PID	=> $$, 
					CPROC	=> "$_PRG-$app",
					LOCK	=> "NBD_SERVER");
				if(!$nbdserver_lock) {
					logwarn("Unable to release lock: $nbdserver_lockr");
				}
			}
		}
	}

	if($cmdname eq "REFRESH_NBD") {
		#########################################################
		# Notice that drbd does not need to refresh ... this	#
		# seems to be quite a reliable part of the procotol.	#
		#########################################################
		if($datadetail eq "drbd") {
			return "OK";
		}
	}

	#################################################################
	# Now the command has been defined, actually run it.		#
	#################################################################

	my $rc=undef;
	$r=forknwait("$cmd");
	if($r) {
		logwarn("Error returned from command: $cmd");
		$rc="FAIL-LOCAL";
	}
	if(defined($cmd3)) {
		$r=forknwait("$cmd3 2>/dev/null");
		if($r) {
			logwarn("Error returned from command: $cmd3");
			$rc="FAIL-LOCAL";
		}
	}
	return($rc) if defined($rc);

	#################################################################
	# Now we have successfully managed to stop the relevent		#
	# client or server on the local node, we send the message	#
	# across to the server, though only if the FORWARD option is	#
	# not present, (to keep it from looping around both servers).	#
	#################################################################

	if(exists($args->{FORWARD})) {
		$cmd="$cmdname app=$app";
		if(defined($vg) && defined($lv)) {
			$cmd.="vg=".$args->{VG}." lv=".$args->{LV};
		}
		$r=do_it($cmd);
		if($r eq "OK") {
			return "OK";
		} else {
			return "FAIL-REMOTE";
		}
	} else {
		return "OK";
	}
}

1;

